﻿using System.Collections.Generic;
using System.Text;
using Jayden.Dll.Web.HtmlControls;
using Jayden.Dll.Web.HtmlControls.Generics;

namespace Jayden.Dll.Web.Scripts
{
	public class JsEntry
	{

		private string m_Key;
		private StringBuilder m_Builder;
		private JsStringBuilder m_JsBuilder;

		public JsEntry(string key)
		{
			m_Key = key;
			m_Builder = new StringBuilder();
			m_JsBuilder = new JsStringBuilder(0, m_Builder);
		}

		public string Key { get { return m_Key; } }
		public StringBuilder Builder { get { return m_Builder; } }
		public JsStringBuilder JsBuilder { get { return m_JsBuilder; } }

		// http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
		public void AppendModule(string js, bool declare = false, string exportTo = null, params KeyValuePair<string, string>[] parameters)
		{
			StringBuilder names = new StringBuilder();
			StringBuilder values = new StringBuilder();
			foreach (KeyValuePair<string, string> pair in parameters)
			{
				if (names.Length > 0)
				{
					names.Append(", ");
					values.Append(", ");
				}
				names.Append(pair.Key);
				values.Append(pair.Value);
			}
			if (!string.IsNullOrWhiteSpace(exportTo))
			{
				if (declare)
					Builder.Append("var ");
				Builder.Append(exportTo.Trim() + " = ");
			}
			Builder.AppendLine( @"(function (" + names.ToString() + @") {
	" + js + @"
}(" + values.ToString() + "));");
		}

		public void Append(string js)
		{
			Builder.AppendLine(@"(function (jayden, $, console, undefined) {
	" + js + @"
}(JAYDEN, JAYDEN.$, JAYDEN.console));");
		}

		public void AppendOnInit(string js)
		{
			StartOnInit().Append(js);
			EndOnInit();
		}

		public JsStringBuilder StartOnInit() { return JsBuilder.Append("$(function() ").OpenBracket("{", true); }
		public JsStringBuilder EndOnInit() { return JsBuilder.CloseBracket("}", true).Append(");"); }


		public void AppendAjaxSubmit(Form form, params Button[] buttons)
		{
			string js = null;
			if (buttons != null && buttons.Length > 1)
			{
				StringBuilder builder = new StringBuilder();
				builder.Append("var button = null;");
				for (int c = 0; c < buttons.Length; c++)
				{
					builder.Append(@"
	var $button" + c + " = $('#" + buttons[c].Id + @"');
	$button" + c + @".click(function() { button = $(this); });");
				}
					js = builder.ToString() + @"
	$('#" + form.Id + @"').submit(function(e) {
		e.preventDefault();
		return JAYDEN.sfn.submitAjax(this, button);
	});";
			}
			else if (buttons != null && buttons.Length == 1)
				js = @"var $button = $('#" + buttons[0].Id + @"');
	$('#" + form.Id + @"').submit(function(e) {
		e.preventDefault();
		return JAYDEN.sfn.submitAjax(this, $button);
	});";
			else
				js = @"$('#" + form.Id + @"').submit(function(e) {
		e.preventDefault();
		return JAYDEN.sfn.submitAjax(this, null);
	});";
			AppendOnInit(js);
		}

		public void AppendAjaxHandler(string js)
		{
			Builder.AppendLine(@"JAYDEN.ajax.handlers.push({
	handle: function(data, textStatus, jqXHR) {
		" + js + @"
	}
});");
		}

		public void AppendAjaxHtmlHandler(HtmlElement elt, bool withSeqNo, bool withDisabled)
		{
			StringBuilder builder = new StringBuilder();
			builder.Append(@"if(data." + elt.Id + @") {");
			if (withDisabled)
			{
				// allow client side enabling/disabling of controls via json request
				builder.Append(@"
			if(data." + elt.Id + @".disabled !== undefined) {
				if(data." + elt.Id + @".disabled)
					$('#" + elt.Id + @"').attr('disabled','disabled');
				else
					$('#" + elt.Id + @"').removeAttr('disabled');
			}");
			}
			if (withSeqNo)
			{
				// add client side handling of seqNo by saving the last value into data('seq-no')
				// and comparing it with the received value, updating the html only when the new seqNo is higher
				builder.Append(@"
			if(data." + elt.Id + @".seqNo !== undefined) {
				var " + elt.Id + @"LastSeqNo = $('#" + elt.Id + @"').data('seq-no');
				if(" + elt.Id + @"LastSeqNo !== undefined && data." + elt.Id + @".seqNo < " + elt.Id + @"LastSeqNo)
					return;
				$('#" + elt.Id + @"').data('seq-no', data." + elt.Id + @".seqNo);
			}");
			}
			builder.Append(@"
			if(data." + elt.Id + @".html !== undefined) {
				$('#" + elt.Id + @"').html(data." + elt.Id + @".html);
			}
		}");
			AppendAjaxHandler(builder.ToString());
		}
	}
}
